#!/usr/bin/env node
// @ts-check
const fs = require('fs')
const path = require('path')

const FILE_DIR = './data/msn'
const stat_res_time = false

/**
 * worker
 * @param {string} filename
 */
async function worker(filename) {
    try {
        let maxts = '' // max timestamp
        let pageMap = {}
        let callMap = {}
        let totalReq = 0
        let totalLines = 0

        function statLine(r) {
            totalLines++

            const v = r.split(',')
            maxts = v[0] // timestamp
            totalReq += Number(v[3]) // size

            const pg = v[1] + '|' + v[2]
            if (!pageMap[pg]) pageMap[pg] = true // cache page

            if (stat_res_time) {
                // stat system call vars
                const sc = Number(v[5])
                if (!callMap[sc]) callMap[sc] = 1
                else callMap[sc]++
            }
        }

        const fd = fs.openSync(path.join(FILE_DIR, filename), 'r')
        let buf = Buffer.alloc(65536 * 1024)
        let bufpos = 0
        let bufread = 0

        while (true) {
            bufread = fs.readSync(fd, buf, { offset: bufpos, length: buf.length - bufpos })
            const len = bufpos + bufread;
            // console.log(bufpos, bufread)
            let pos = 0
            while (true) {
                let nxt = buf.indexOf('\n', pos, 'ascii')
                if (nxt < 0 || nxt >= len)
                    break; // no new line
                statLine(buf.subarray(pos, nxt).toString('ascii'))
                pos = nxt + 1;
            }
            if (pos === len) {
                bufpos = 0; // restart from begin
            }
            else {
                buf.fill(buf.subarray(pos, len).toString('ascii'))
                bufpos = len - pos
            }

            if (bufread === 0) {
                if (bufpos > 0) {
                    statLine(buf.subarray(0, bufpos).toString('ascii'))
                }
                break;
            }
        }

        fs.closeSync(fd)

        console.log(`[${filename}]`, totalLines, maxts, Object.keys(pageMap).length, totalReq)
        if (stat_res_time) {
            for (const k in callMap)
                console.log(`${k},${callMap[k]}`)
        }

    } catch (e) {
        console.error(e)
    }
}

const filelist = fs.readdirSync(FILE_DIR).filter(v => v.endsWith('.csv'))

console.log('[fn] line timespan metadata request')
for (const fn of filelist)
    worker(fn)
